let code = require('../../../constant/code');
let scheduler = require('pomelo-scheduler');
let logger = require('pomelo-logger').getLogger('logic');
let utils = require('../../../util/utils');
let enumeration = require('../../../constant/enumeration');
let pomelo = require('pomelo');
let moment = require('moment');
let Union = require('./union');
let rpcAPI = require('../../../API/rpcAPI');
let commonDao = require('../../../dao/commonDao');
let userDao = require('../../../dao/userDao');
let userInfoServices = require('../../../services/userInfoServices');
let dispatch = require('../../../util/dispatcher');
let robotlogger = require('pomelo-logger').getLogger('robot');
let isShowLog = true;

let exp = module.exports;

let UNION_MAX_DELAY_DELETE_TIME = 24 * 60 * 60 * 1000;
let IS_AUTO_ADD_SCORE = true; //是否自动加分
let IS_WIN_LOSE_LIMIT = true; //是否输赢限制
exp.init = function () {
    this.unionList = {};
    this.showLogTime = 0;
    this.scheduleJobID = -1;
    this.startScheduler();
};



exp.beforeShutdown = async function (cb) {
    scheduler.cancelJob(this.dailyTaskSchedulerID);
    scheduler.cancelJob(this.weekTaskSchedulerID);
    await commonDao.updateAllData("userModel", { $or: [{ roomID: { $ne: "" } }, { frontendId: { $ne: "" } }] }, { roomID: "", frontendId: "" });
    cb();
};

let scheduleTask = function (data) {
    let self = data.manager;
    let timeNow = new Date().toLocaleString();
    logger.info(pomelo.app.curServer.id + ':room manager schedule task');
    logger.info(timeNow);
    // 输出现有缓存联盟的数量
    let count = 0;
    for (let key in self.unionList) {
        if (self.unionList.hasOwnProperty(key)) {
            let union = self.unionList[key];
            logger.info('union id: ' + key);
            if (union.isShouldDelete(UNION_MAX_DELAY_DELETE_TIME)) {
                union.onDestroy();
                delete self.unionList[key];
                logger.info('delete union id:' + key);
            } else {
                count++;
            }
        }
    }
    logger.info('union count:' + count);
};

exp.dailyTaskScheduler = function () {
    logger.info('dailyTaskSchedulerClearData');
    for (let key in exp.unionList) {
        if (exp.unionList.hasOwnProperty(key)) {
            let union = exp.unionList[key];
            union.dailyClear();
        }
    }
};

exp.startScheduler = function () {
    this.scheduleJobID = scheduler.scheduleJob({ period: 60 * 60 * 1000 }, scheduleTask, { manager: this });

    this.dailyTaskSchedulerID = scheduler.scheduleJob('0 0 0 * * *', exp.dailyTaskScheduler);

    //0,10,20,30,40,
    this.robotScheduler = scheduler.scheduleJob('0/5 * * * * *', () => {
        let curTime = moment().format('x');
        if (curTime > this.showLogTime) {
            // robotlogger.info('[robotScheduler] [ -------------- Robot Create And Join -------------- ]');
            this.showLogTime = moment().add(1, 'm').format('x');
        }
        this.checkEmptyRoomList();
    });

};

exp.stopScheduler = function () {
    scheduler.cancelJob(this.scheduleJobID);
    scheduler.cancelJob(this.dailyTaskSchedulerID);
};

exp.beforeShutdown = function (cb) {
    this.stopScheduler();
    cb();
};

exp.getUnion = async function (unionID) {
    if (!this.unionList[unionID]) {
        let union = new Union(unionID);
        this.unionList[unionID] = union;
        await union.init();
    }
    return this.unionList[unionID];
};


exp.removeUnionCache = function (unionID) {
    if (!this.unionList[unionID]) return;
    let union = this.unionList[unionID];
    union.onDestroy();
    delete this.unionList[unionID];
    logger.info('delete union id:' + unionID);
};


exp.joinRoom = async function (userInfo, roomID) {
    let union = this.getUnionByRoomID(roomID);
    if (!union) {
        return code.ROOM_NOT_EXIST;
    }
    return await union.joinRoom(roomID, userInfo);
};

//加入旁观
exp.joinWatch = async function (userInfo, roomID) {
    let union = this.getUnionByRoomID(roomID);
    if (!union) {
        return code.ROOM_NOT_EXIST;
    }
    return await union.joinWatch(roomID, userInfo);
};


exp.leaveRoom = async function (roomID, uid) {
    let roomFrame = this.getRoomFrameByID(roomID);
    if (!roomFrame) return;
    return await roomFrame.userOffLine(uid);
};

exp.dismissRoom = function (roomID) {
    let union = this.getUnionByRoomID(roomID);
    if (!union) {
        logger.warn('dismissRoom', 'union not exit');
        return;
    }
    union.destroyRoom(roomID);
};

exp.getRoomFrameByID = function (roomID) {
    for (let key in this.unionList) {
        if (this.unionList.hasOwnProperty(key)) {
            if (!!this.unionList[key].roomList[roomID]) {
                return this.unionList[key].roomList[roomID];
            }
        }
    }
    return null;
}

exp.getUnionByRoomID = function (roomID) {
    for (let key in this.unionList) {
        if (this.unionList.hasOwnProperty(key)) {
            if (!!this.unionList[key].roomList[roomID]) {
                return this.unionList[key];
            }
        }
    }
    return null;
};

exp.isUserInRoom = function (uid, roomID) {
    let roomFrame = this.getRoomFrameByID(roomID);
    return roomFrame && roomFrame.isUserInRoom(uid);
};

exp.createNewRoomID = function () {
    let gameServers = pomelo.app.getServersByType('game');
    let curServerIndex = 0;
    for (let i = 0; i < gameServers.length; ++i) {
        if (gameServers[i].id === pomelo.app.curServer.id) {
            curServerIndex = i;
            break;
        }
    }
    let roomID = -1;
    let min = Math.floor(100000 / gameServers.length) + 1;
    let max = Math.floor(1000000 / gameServers.length) - 1;
    do {
        roomID = utils.getRandomNum(min, max) * gameServers.length + curServerIndex;
    } while (!!this.getRoomFrameByID(roomID));
    return roomID;
};

//查找空的房间
exp.checkEmptyRoomList = async () => {



    let goldRoom = this.unionList[1];
    if (goldRoom) {
        let roomList = goldRoom.roomList;
        if (roomList != {}) {
            for (let roomID in roomList) {
                if (roomList[roomID]) {
                    let curRoom = roomList[roomID];
                    let gameRule = curRoom.gameRule;
                    let gameType = curRoom.gameType;
                    let roomType = curRoom.creatorInfo.roomType;

                    let curCount = utils.getLength(curRoom.userArr);
                    if (curCount >= curRoom.chairCount) {
                        if (roomType == enumeration.roomType.GOLD && curRoom.curBureau == 0) {
                            for (let uid in curRoom.userArr) {
                                let playStatus = curRoom.userArr[uid].playStatus;
                                if (playStatus == 0 && curRoom.userArr[uid].userInfo.isRobot) {
                                    let union = await this.getUnion(1);
                                    await union.robotReady(uid, roomID);
                                }
                            }
                        }
                        continue;
                    }
                    //金币场
                    if (roomType == enumeration.roomType.GOLD) {
                        if (curRoom.roomDismissed) {
                            if (isShowLog) robotlogger.info(`[robotScheduler] room Dismissed = ${curRoom.roomDismissed} gameType = ${gameType} `);
                            continue;//房间已解散
                        }
                        let robotQuery = { isRobot: true };
                        let sortData = { lastLoginTime: 1 };
                        let robotAutoUser = await commonDao.findData('userModel', robotQuery, sortData);
                        let maxCount = 1;
                        let successCount = 0;
                        if (robotAutoUser && robotAutoUser.length > 0) {
                            for (let i = 0; i < robotAutoUser.length && successCount < maxCount; i++) {
                                let curUser = robotAutoUser[i];
                                if (curUser) {
                                    curUser = await this.checkUserScore(curUser, gameRule);
                                    if (isShowLog) robotlogger.info(`[robotScheduler] join success score limited uid = ${curUser.uid}  scoreLowLimit = ${gameRule.scoreLowLimit}`);
                                    if (curUser) {
                                        let joinCode = await this.robotJoinRoom(1, curUser, roomID);
                                        await userDao.unlockRobotData(curUser.uid);
                                        if (isShowLog) robotlogger.info(`[robotScheduler] join success score joinCode = ${joinCode} `);
                                        successCount += 1;
                                    }
                                }

                            }
                        }
                    }
                }
            }
        }
    }

}


//机器人进入房间
exp.robotJoinRoom = async function (unionID, userData, roomID) {

    let union = await this.getUnion(unionID);
    if (!union) {
        robotlogger.info(`[robotScheduler] robotJoinRoom union is not exit`);
        return;
    }
    if (!userData) {
        return;
    }
    let userInfo = userInfoServices.buildGameRoomUserInfo(userData);
    let resCode = await union.joinRoom(roomID, userInfo);
    if (isShowLog) robotlogger.info(`[robotScheduler][${unionID}]robotJoinRoom robotUid = ${userData.uid} nikeName = ${userData.nickname} resCode = ${resCode}`);
    //如果机器人进入成功
    if (resCode == code.OK) {

        // let randTime = utils.getRandomNum(500, 2000);
        // setTimeout(async () => {

        // }, randTime);
        let readyCode = code.OK;
        if (userData.gameType < 200) {
            readyCode = await union.robotReady(userData.uid, roomID);
        }
        // robotlogger.info(`[robotScheduler]  Robot Ready Code = ${ readyCode }`);
        if (readyCode == code.FAIL) {
            robotlogger.info(`[robotScheduler]  Robot Ready Code = ${readyCode}`);
            await union.userLeaveRoom(userData.uid, roomID);
        } else {
            //更新机器人信息
            let frontendId = dispatch.dispatch(userData.uid, pomelo.app.getServersByType('connector'));
            let lastLoginTime = moment().format('x');
            await userDao.updateUserDataByUid(userData.uid, { frontendId: frontendId.id, 'lastLoginTime': lastLoginTime });
        }

    }
    return resCode;
}



//处理玩家分数问题
exp.checkUserScore = async function (autoUser, gameRule) {

    //查询玩家分数
    let scoreLowLimit = gameRule.scoreLowLimit;
    let randomScore = scoreLowLimit * utils.getRandomNum(5, 10) + utils.getRandomNum(1, 9) * 1000;
    if (autoUser.goldScore < randomScore) {
        let curScore = parseInt(randomScore) - parseInt(autoUser.goldScore);
        let detail = { score: curScore };
        await userInfoServices.addGoldScore(autoUser, detail)
    }
    return await userDao.getUserDataByUid(autoUser.uid);

}
